/**
 * 冲突检测功能模块
 * 负责处理任务块之间的设备冲突检测和标记
 */
export class ConflictDetection {
  constructor(vm) {
    this.vm = vm
  }

  /**
   * 验证指定卫星的任务块是否有重叠
   * @param {string} satelliteId - 卫星ID
   * @returns {boolean} - 是否没有重叠
   */
  validateNoOverlap(satelliteId) {
    const satelliteTasks = this.vm.scheduleItems
      .filter(item => item.satelliteId === satelliteId)
      .sort((a, b) => a.startDay - b.startDay)

    for (let i = 0; i < satelliteTasks.length - 1; i++) {
      const currentTask = satelliteTasks[i]
      const nextTask = satelliteTasks[i + 1]
      
      const currentEnd = currentTask.startDay + currentTask.duration
      
      if (currentEnd > nextTask.startDay) {
        return false
      }
    }
    
    return true
  }

  /**
   * 检测设备使用冲突
   * @param {string} satelliteId - 可选，指定卫星ID进行检测
   * @returns {Array} - 冲突列表
   */
  detectDeviceConflicts(satelliteId = null) {
    // 获取要检测的任务块
    let tasksToCheck = this.vm.scheduleItems
    if (satelliteId) {
      tasksToCheck = tasksToCheck.filter(task => task.satelliteId === satelliteId)
    }
    
    // 收集所有设备使用情况
    const allDeviceUsage = new Map() // deviceName -> [usage records]
    
    tasksToCheck.forEach(task => {
      // 如果任务有startDate，使用startDate；否则根据任务的起始日期计算
      let baseDate = task.startDate
      if (!baseDate && this.vm.startDate && task.startDay !== undefined) {
        // 使用全局起始日期 + 任务起始天数
        const globalStartDate = new Date(this.vm.startDate)
        globalStartDate.setDate(globalStartDate.getDate() + task.startDay - 1)
        baseDate = globalStartDate.toISOString().split('T')[0]
      }
      
      const deviceUsageMap = this.calculateDeviceUsageDates(task, baseDate)
      
      // 合并到全局设备使用记录中
      deviceUsageMap.forEach((usageRecords, deviceName) => {
        if (!allDeviceUsage.has(deviceName)) {
          allDeviceUsage.set(deviceName, [])
        }
        allDeviceUsage.get(deviceName).push(...usageRecords)
      })
    })
    
    // 检测冲突 - 基于设备容量
    const conflicts = []
    allDeviceUsage.forEach((usageRecords, deviceName) => {
      // 按日期排序
      usageRecords.sort((a, b) => a.date.localeCompare(b.date))
      
      // 按日期分组，检查每天的使用情况
      const dateGroups = new Map()
      usageRecords.forEach(record => {
        if (!dateGroups.has(record.date)) {
          dateGroups.set(record.date, [])
        }
        dateGroups.get(record.date).push(record)
      })
      
      dateGroups.forEach((records, date) => {
        // 获取该日期内所有任务块中该设备的最小容量作为判定标准
        const deviceCapacity = this.getMinDeviceCapacityForDate(deviceName, records)
        
        // 统计同一天使用该设备的不同卫星数量
        const satelliteSet = new Set(records.map(r => r.satelliteId))
        const satelliteCount = satelliteSet.size
        
        // 如果使用的卫星数量超过设备容量，则为冲突
        if (satelliteCount > deviceCapacity) {
          conflicts.push({
            deviceName,
            date,
            deviceCapacity,
            actualUsage: satelliteCount,
            conflictType: 'capacity', // 容量冲突
            conflictingTasks: records.map(r => ({
              taskId: r.taskId,
              taskTitle: r.taskTitle,
              satelliteId: r.satelliteId,
              dayIndex: r.dayIndex
            }))
          })
        }
      })
    })
    

    
    // 返回检测结果
    return conflicts
  }



  /**
   * 计算任务块中每个设备的具体使用日期
   * @param {Object} task - 任务块对象
   * @param {string} baseDate - 基准日期
   * @returns {Map} - 设备使用日期映射
   */
  calculateDeviceUsageDates(task, baseDate) {
    const deviceUsageMap = new Map()
    
    // 如果没有基准日期，使用任务的起始日期
    if (!baseDate && !task.startDate) {
      return deviceUsageMap
    }
    
    // 解析基准日期（可能是字符串格式的日期或者数字格式的天数）
    let startDate
    if (baseDate) {
      startDate = new Date(baseDate)
    } else if (task.startDate) {
      startDate = new Date(task.startDate)
    }
    
    // 遍历每日设备配置
    if (task.dayConfigs && Array.isArray(task.dayConfigs)) {
      task.dayConfigs.forEach((dayDevices, dayIndex) => {
        if (dayDevices && Array.isArray(dayDevices)) {
          // 计算当天的具体日期
          const currentDate = new Date(startDate)
          currentDate.setDate(startDate.getDate() + dayIndex)
          const dateString = currentDate.toISOString().split('T')[0] // YYYY-MM-DD格式
          
          // 记录每个设备在这一天的使用情况
          dayDevices.forEach(deviceName => {
            if (!deviceUsageMap.has(deviceName)) {
              deviceUsageMap.set(deviceName, [])
            }
            deviceUsageMap.get(deviceName).push({
              date: dateString,
              dayIndex: dayIndex,
              taskId: task.id,
              taskTitle: task.title,
              satelliteId: task.satelliteId,
              taskStartDay: task.startDay,
              taskDuration: task.duration,
              taskEndDay: task.startDay + task.duration - 1
            })
          })
        }
      })
    } else if (task.requiredDevices && Array.isArray(task.requiredDevices)) {
      // 兼容旧版本：如果没有 dayConfigs，使用 requiredDevices 作为每天的设备配置
      for (let dayIndex = 0; dayIndex < (task.duration || 1); dayIndex++) {
        const currentDate = new Date(startDate)
        currentDate.setDate(startDate.getDate() + dayIndex)
        const dateString = currentDate.toISOString().split('T')[0]
        
        task.requiredDevices.forEach(deviceName => {
          if (!deviceUsageMap.has(deviceName)) {
            deviceUsageMap.set(deviceName, [])
          }
          deviceUsageMap.get(deviceName).push({
            date: dateString,
            dayIndex: dayIndex,
            taskId: task.id,
            taskTitle: task.title,
            satelliteId: task.satelliteId,
            taskStartDay: task.startDay,
            taskDuration: task.duration,
            taskEndDay: task.startDay + task.duration - 1
          })
        })
      }
    } else if (task.requiredDevice) {
      // 兼容更旧版本：如果只有 requiredDevice 字段
      for (let dayIndex = 0; dayIndex < (task.duration || 1); dayIndex++) {
        const currentDate = new Date(startDate)
        currentDate.setDate(startDate.getDate() + dayIndex)
        const dateString = currentDate.toISOString().split('T')[0]
        
        if (!deviceUsageMap.has(task.requiredDevice)) {
          deviceUsageMap.set(task.requiredDevice, [])
        }
        deviceUsageMap.get(task.requiredDevice).push({
          date: dateString,
          dayIndex: dayIndex,
          taskId: task.id,
          taskTitle: task.title,
          satelliteId: task.satelliteId,
          taskStartDay: task.startDay,
          taskDuration: task.duration,
          taskEndDay: task.startDay + task.duration - 1
        })
      }
    }
    
    return deviceUsageMap
  }

  /**
   * 获取指定日期内所有任务块中该设备的最小容量作为冲突判定标准
   * @param {string} deviceName - 设备名称
   * @param {Array} records - 使用记录
   * @returns {number} - 最小设备容量
   */
  getMinDeviceCapacityForDate(deviceName, records) {
    let minCapacity = null
    
    // 遍历该日期的所有使用记录，查找任务块中设置的设备容量
    records.forEach(record => {
      const task = this.vm.scheduleItems.find(item => item.id === record.taskId)
      if (task && task.deviceCapacities && task.deviceCapacities[deviceName] !== undefined) {
        const taskDeviceCapacity = parseInt(task.deviceCapacities[deviceName])
        if (taskDeviceCapacity > 0) {
          if (minCapacity === null || taskDeviceCapacity < minCapacity) {
            minCapacity = taskDeviceCapacity
          }
        }
      }
    })
    
    // 如果没有任务块设置了该设备的容量，使用设备默认容量
    if (minCapacity === null) {
      minCapacity = this.getDeviceCapacity(deviceName)
    }
    
    return minCapacity
  }

  /**
   * 获取设备容量
   * @param {string} deviceName - 设备名称
   * @returns {number} - 设备容量
   */
  getDeviceCapacity(deviceName) {
    // 优先从任务块中获取设备容量配置
    const taskBlockCapacity = this.getDeviceCapacityFromTasks(deviceName)
    if (taskBlockCapacity !== null) {
      return taskBlockCapacity
    }
    
    // 在测试中心设备中查找
    const testCenterDevice = this.vm.availableDevices.testCenter.find(device => device.name === deviceName)
    if (testCenterDevice && testCenterDevice.capacity !== undefined) {
      return testCenterDevice.capacity
    }
    
    // 在总装设备中查找
    const assemblyDevice = this.vm.availableDevices.assembly.find(device => device.name === deviceName)
    if (assemblyDevice && assemblyDevice.capacity !== undefined) {
      return assemblyDevice.capacity
    }
    
    // 如果没找到设备或没有容量信息，默认容量为1
    return 1
  }

  /**
   * 从任务块中获取设备容量配置
   * @param {string} deviceName - 设备名称
   * @returns {number|null} - 设备容量或null
   */
  getDeviceCapacityFromTasks(deviceName) {
    // 遍历所有任务块，查找该设备的容量配置
    for (const task of this.vm.scheduleItems) {
      if (task.deviceCapacities && task.deviceCapacities[deviceName] !== undefined) {
        const capacity = task.deviceCapacities[deviceName]
        return capacity
      }
    }
    return null // 没有在任务块中找到该设备的容量配置
  }

  /**
   * 标记冲突任务块
   * @param {Array} conflicts - 冲突列表
   */
  markConflictingTasks(conflicts) {
    // 首先清除所有任务块的冲突标记
    this.vm.scheduleItems.forEach(item => {
      item.hasConflict = false
      item.conflictDays = [] // 记录具体冲突的天数索引
    })
    
    // 收集每个任务的冲突天数
    const taskConflictDays = new Map() // taskId -> Set of dayIndex
    
    conflicts.forEach(conflict => {
      conflict.conflictingTasks.forEach(task => {
        if (!taskConflictDays.has(task.taskId)) {
          taskConflictDays.set(task.taskId, new Set())
        }
        
        // 如果冲突信息包含dayIndex，记录具体的天数
        if (task.dayIndex !== undefined) {
          taskConflictDays.get(task.taskId).add(task.dayIndex)
        } else {
          // 如果没有具体天数信息，标记整个任务块为冲突
          const taskItem = this.vm.scheduleItems.find(item => item.id === task.taskId)
          if (taskItem) {
            for (let i = 0; i < taskItem.duration; i++) {
              taskConflictDays.get(task.taskId).add(i)
            }
          }
        }
      })
    })
    
    // 给任务块添加冲突标记
    this.vm.scheduleItems.forEach(item => {
      if (taskConflictDays.has(item.id)) {
        const conflictDaysSet = taskConflictDays.get(item.id)
        item.conflictDays = Array.from(conflictDaysSet).sort((a, b) => a - b)
        item.hasConflict = item.conflictDays.length > 0
      }
    })
  }

  /**
   * 清除所有冲突标记
   */
  clearConflictMarks() {
    this.vm.scheduleItems.forEach(item => {
      item.hasConflict = false
      item.conflictDays = [] // 清除具体冲突的天数记录
    })
  }
}